//
//  LoginBean.swift
//  test-ios
//
//  Created by wyz5204 on 2023/6/1.
//

import Foundation

// MARK: - LoginBean
struct LoginBean: Codable {
    let userInfo: UserInfo
    let mag: Int
    let versionHint, im: String
    let grayLevelVerify: Bool
    let rdToken: String
    let grayscaleList: [JSONAny]
    let isNewUser: JSONNull?
    let token: String
}

// MARK: LoginBean convenience initializers and mutators

extension LoginBean {
    init(data: Data) throws {
        self = try newJSONDecoder().decode(LoginBean.self, from: data)
    }

    init(_ json: String, using encoding: String.Encoding = .utf8) throws {
        guard let data = json.data(using: encoding) else {
            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
        }
        try self.init(data: data)
    }

    init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        userInfo: UserInfo? = nil,
        mag: Int? = nil,
        versionHint: String? = nil,
        im: String? = nil,
        grayLevelVerify: Bool? = nil,
        rdToken: String? = nil,
        grayscaleList: [JSONAny]? = nil,
        isNewUser: JSONNull?? = nil,
        token: String? = nil
    ) -> LoginBean {
        return LoginBean(
            userInfo: userInfo ?? self.userInfo,
            mag: mag ?? self.mag,
            versionHint: versionHint ?? self.versionHint,
            im: im ?? self.im,
            grayLevelVerify: grayLevelVerify ?? self.grayLevelVerify,
            rdToken: rdToken ?? self.rdToken,
            grayscaleList: grayscaleList ?? self.grayscaleList,
            isNewUser: isNewUser ?? self.isNewUser,
            token: token ?? self.token
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(), encoding: encoding)
    }
}

// MARK: - UserInfo
struct UserInfo: Codable {
    let id, username: JSONNull?
    let name: String
    let telephone, password: JSONNull?
    let sex: Int
    let job: JSONNull?
    let userImg: String
    let mobile: String
    let email, loginTime, accountFlag, createBy: JSONNull?
    let createTime, updateBy, updateTime, pwdErrorNum: JSONNull?
    let remarks, delFlag, accountType, identityCard: JSONNull?
    let isSuper, officeSpace, sourceFlag, sourceID: JSONNull?
    let deptID, roleID, newPassword, deptName: JSONNull?
    let roleName, userID, label, publicKey: JSONNull?
    let uniqueID, deptIDSet, idSet: JSONNull?
    let crmID: String
    let isCustomerService: Int
    let isCustomerServiceType: JSONNull?
    let invitedType: Int
    let outTime: JSONNull?
    let company: String
    let dept, type, isOwner, orgIDS: JSONNull?
    let isRelation: Int
    let handoverFlag, userSource, names, roleIDS: JSONNull?
    let jobs, mobiles, emails, sexs: JSONNull?
    let startTime, endTime, orderFlag, deptMap: JSONNull?
    let roleMap, userHeadImgColor, userHeadImgText, linkFlag: JSONNull?
    let linkSource, userIdentity, isOnline: JSONNull?
    let userNameID: String
    let areaCode: JSONNull?
    let internationalAreaCode: String
    let rongdaFlag: JSONNull?

    enum CodingKeys: String, CodingKey {
        case id, username, name, telephone, password, sex, job, userImg, mobile, email, loginTime, accountFlag, createBy, createTime, updateBy, updateTime, pwdErrorNum, remarks, delFlag, accountType, identityCard, isSuper, officeSpace, sourceFlag
        case sourceID = "sourceId"
        case deptID = "deptId"
        case roleID = "roleId"
        case newPassword, deptName, roleName
        case userID = "userId"
        case label, publicKey
        case uniqueID = "uniqueId"
        case deptIDSet = "deptIdSet"
        case idSet
        case crmID = "crmId"
        case isCustomerService, isCustomerServiceType, invitedType, outTime, company, dept, type, isOwner
        case orgIDS = "orgIds"
        case isRelation, handoverFlag, userSource, names
        case roleIDS = "roleIds"
        case jobs, mobiles, emails, sexs, startTime, endTime, orderFlag, deptMap, roleMap, userHeadImgColor, userHeadImgText, linkFlag, linkSource, userIdentity, isOnline
        case userNameID = "userNameId"
        case areaCode, internationalAreaCode, rongdaFlag
    }
}

// MARK: UserInfo convenience initializers and mutators

extension UserInfo {
    init(data: Data) throws {
        self = try newJSONDecoder().decode(UserInfo.self, from: data)
    }

    init(_ json: String, using encoding: String.Encoding = .utf8) throws {
        guard let data = json.data(using: encoding) else {
            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
        }
        try self.init(data: data)
    }

    init(fromURL url: URL) throws {
        try self.init(data: try Data(contentsOf: url))
    }

    func with(
        id: JSONNull?? = nil,
        username: JSONNull?? = nil,
        name: String? = nil,
        telephone: JSONNull?? = nil,
        password: JSONNull?? = nil,
        sex: Int? = nil,
        job: JSONNull?? = nil,
        userImg: String? = nil,
        mobile: String? = nil,
        email: JSONNull?? = nil,
        loginTime: JSONNull?? = nil,
        accountFlag: JSONNull?? = nil,
        createBy: JSONNull?? = nil,
        createTime: JSONNull?? = nil,
        updateBy: JSONNull?? = nil,
        updateTime: JSONNull?? = nil,
        pwdErrorNum: JSONNull?? = nil,
        remarks: JSONNull?? = nil,
        delFlag: JSONNull?? = nil,
        accountType: JSONNull?? = nil,
        identityCard: JSONNull?? = nil,
        isSuper: JSONNull?? = nil,
        officeSpace: JSONNull?? = nil,
        sourceFlag: JSONNull?? = nil,
        sourceID: JSONNull?? = nil,
        deptID: JSONNull?? = nil,
        roleID: JSONNull?? = nil,
        newPassword: JSONNull?? = nil,
        deptName: JSONNull?? = nil,
        roleName: JSONNull?? = nil,
        userID: JSONNull?? = nil,
        label: JSONNull?? = nil,
        publicKey: JSONNull?? = nil,
        uniqueID: JSONNull?? = nil,
        deptIDSet: JSONNull?? = nil,
        idSet: JSONNull?? = nil,
        crmID: String? = nil,
        isCustomerService: Int? = nil,
        isCustomerServiceType: JSONNull?? = nil,
        invitedType: Int? = nil,
        outTime: JSONNull?? = nil,
        company: String? = nil,
        dept: JSONNull?? = nil,
        type: JSONNull?? = nil,
        isOwner: JSONNull?? = nil,
        orgIDS: JSONNull?? = nil,
        isRelation: Int? = nil,
        handoverFlag: JSONNull?? = nil,
        userSource: JSONNull?? = nil,
        names: JSONNull?? = nil,
        roleIDS: JSONNull?? = nil,
        jobs: JSONNull?? = nil,
        mobiles: JSONNull?? = nil,
        emails: JSONNull?? = nil,
        sexs: JSONNull?? = nil,
        startTime: JSONNull?? = nil,
        endTime: JSONNull?? = nil,
        orderFlag: JSONNull?? = nil,
        deptMap: JSONNull?? = nil,
        roleMap: JSONNull?? = nil,
        userHeadImgColor: JSONNull?? = nil,
        userHeadImgText: JSONNull?? = nil,
        linkFlag: JSONNull?? = nil,
        linkSource: JSONNull?? = nil,
        userIdentity: JSONNull?? = nil,
        isOnline: JSONNull?? = nil,
        userNameID: String? = nil,
        areaCode: JSONNull?? = nil,
        internationalAreaCode: String? = nil,
        rongdaFlag: JSONNull?? = nil
    ) -> UserInfo {
        return UserInfo(
            id: id ?? self.id,
            username: username ?? self.username,
            name: name ?? self.name,
            telephone: telephone ?? self.telephone,
            password: password ?? self.password,
            sex: sex ?? self.sex,
            job: job ?? self.job,
            userImg: userImg ?? self.userImg,
            mobile: mobile ?? self.mobile,
            email: email ?? self.email,
            loginTime: loginTime ?? self.loginTime,
            accountFlag: accountFlag ?? self.accountFlag,
            createBy: createBy ?? self.createBy,
            createTime: createTime ?? self.createTime,
            updateBy: updateBy ?? self.updateBy,
            updateTime: updateTime ?? self.updateTime,
            pwdErrorNum: pwdErrorNum ?? self.pwdErrorNum,
            remarks: remarks ?? self.remarks,
            delFlag: delFlag ?? self.delFlag,
            accountType: accountType ?? self.accountType,
            identityCard: identityCard ?? self.identityCard,
            isSuper: isSuper ?? self.isSuper,
            officeSpace: officeSpace ?? self.officeSpace,
            sourceFlag: sourceFlag ?? self.sourceFlag,
            sourceID: sourceID ?? self.sourceID,
            deptID: deptID ?? self.deptID,
            roleID: roleID ?? self.roleID,
            newPassword: newPassword ?? self.newPassword,
            deptName: deptName ?? self.deptName,
            roleName: roleName ?? self.roleName,
            userID: userID ?? self.userID,
            label: label ?? self.label,
            publicKey: publicKey ?? self.publicKey,
            uniqueID: uniqueID ?? self.uniqueID,
            deptIDSet: deptIDSet ?? self.deptIDSet,
            idSet: idSet ?? self.idSet,
            crmID: crmID ?? self.crmID,
            isCustomerService: isCustomerService ?? self.isCustomerService,
            isCustomerServiceType: isCustomerServiceType ?? self.isCustomerServiceType,
            invitedType: invitedType ?? self.invitedType,
            outTime: outTime ?? self.outTime,
            company: company ?? self.company,
            dept: dept ?? self.dept,
            type: type ?? self.type,
            isOwner: isOwner ?? self.isOwner,
            orgIDS: orgIDS ?? self.orgIDS,
            isRelation: isRelation ?? self.isRelation,
            handoverFlag: handoverFlag ?? self.handoverFlag,
            userSource: userSource ?? self.userSource,
            names: names ?? self.names,
            roleIDS: roleIDS ?? self.roleIDS,
            jobs: jobs ?? self.jobs,
            mobiles: mobiles ?? self.mobiles,
            emails: emails ?? self.emails,
            sexs: sexs ?? self.sexs,
            startTime: startTime ?? self.startTime,
            endTime: endTime ?? self.endTime,
            orderFlag: orderFlag ?? self.orderFlag,
            deptMap: deptMap ?? self.deptMap,
            roleMap: roleMap ?? self.roleMap,
            userHeadImgColor: userHeadImgColor ?? self.userHeadImgColor,
            userHeadImgText: userHeadImgText ?? self.userHeadImgText,
            linkFlag: linkFlag ?? self.linkFlag,
            linkSource: linkSource ?? self.linkSource,
            userIdentity: userIdentity ?? self.userIdentity,
            isOnline: isOnline ?? self.isOnline,
            userNameID: userNameID ?? self.userNameID,
            areaCode: areaCode ?? self.areaCode,
            internationalAreaCode: internationalAreaCode ?? self.internationalAreaCode,
            rongdaFlag: rongdaFlag ?? self.rongdaFlag
        )
    }

    func jsonData() throws -> Data {
        return try newJSONEncoder().encode(self)
    }

    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
        return String(data: try self.jsonData(), encoding: encoding)
    }
}
